<?php

namespace Yolo\Captcha\Core\Engines;

use Yolo\Captcha\Core\CaptchaResult;
use Yolo\Captcha\Core\Helper;

/**
 * 简单算术类
 */
class SimpleArithmetic implements CaptchaInterface
{

    public function create(array $config): CaptchaResult
    {
        $n1 = $this->getNumber(0, 50);
        $n2 = $this->getNumber(0, 50);

        $operator = $this->getOperator($n1, $n2);

        $answer = (string)match($operator) {
            '+' => $n1 + $n2,
            '-' => $n1 - $n2,
            'x' => $n1 * $n2,
            '÷' => $n1 / $n2,
        };

        $texts = [$n1, $operator, $n2, '='];
        $textData = array_map(function ($text) {
            $angle = 0;
            if (!in_array($text, ['+', '-', 'x', '÷', '='])) {
                $angle = Helper::getRandomAngle();
            }
            return [
                'text' => $text,
                'color' => Helper::getRandomFontColor(),
                'spacing' => 50,
                'angle' => $angle,
            ];
        }, $texts);

        return new CaptchaResult([
            'text' => implode(' ', $texts),
            'answer' => $answer,
            'textData' => $textData,
        ]);
    }

    private function getOperator(int $n1, int $n2): string
    {
        $supportOperators = ['+', '-', 'x', '÷'];
        if ($n1 >= 10 && $n2 >= 10) { // 两个数都大于等于10，则不计算乘法
            $supportOperators = array_filter($supportOperators, function ($supportOperator) {
                return $supportOperator !== 'x';
            });
        }

        if ($n1 < $n2) { // 第一个数比第二个数小，则不计算减法和除法
            $supportOperators = array_filter($supportOperators, function ($supportOperator) {
                return $supportOperator !== '-' && $supportOperator !== '÷';
            });
        }

        if ($n2 === 0 || $n1 % $n2 !== 0) { // 第一个数不能整除第二个数，则不计算除法
            $supportOperators = array_filter($supportOperators, function ($supportOperator) {
                return $supportOperator !== '÷';
            });
        }

        return $supportOperators[array_rand($supportOperators)];
    }

    private function getNumber(int $min, int $max): int
    {
        return mt_rand($min, $max);
    }
}
